package cn.skylark.wcm.common.util;

import com.sun.org.apache.xml.internal.security.utils.Base64;

import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;

/**
 * 用户密码加密
 *
 * @author :chuhl
 * @since 2017年12月4日14:14:18
 */
public class PasswordHelper {
    public static final String UTF_8 = "UTF-8";
    public static final char PADDING_CHAR = '\0';
    static String IV = "1234567891234567";
    static String encryptionKey = "abcdef0123456789";

    /**
     * 字符串加密
     * 1：采用AES/CBC/PKCS5Padding方式实例化
     * 2：AES+encryptionKey方式进行加密处理
     * 3：运用Base64进行编码，生成64位字符串
     *
     * @param plainText 加密字符串
     * @return 加密后字符串
     * @throws Exception
     */
    public  String encrypt(String plainText) throws Exception {
        plainText = padding(plainText);
        Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding ", "SunJCE");
        SecretKeySpec key = new SecretKeySpec(encryptionKey.getBytes(UTF_8), "AES");
        cipher.init(Cipher.ENCRYPT_MODE, key,new IvParameterSpec(IV.getBytes(UTF_8)));
        byte[] bytes = cipher.doFinal(plainText.getBytes(UTF_8));
        String s = Base64.encode(bytes);
        return s;
    }

    /**
     * 字符串解密
     * 1：采用AES/CBC/PKCS5Padding方式实例化
     * 2：AES+encryptionKey方式进行解密处理
     * 3：运用Base64进行编码，还原字符串
     * @param cipherText 解密字符串
     * @return 返回解密后字符串
     * @throws Exception
     */
    public  String decrypt(String cipherText) throws Exception{
        Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding", "SunJCE");
        SecretKeySpec key = new SecretKeySpec(encryptionKey.getBytes(UTF_8), "AES");
        cipher.init(Cipher.DECRYPT_MODE, key,new IvParameterSpec(IV.getBytes(UTF_8)));
        byte[] decoded = Base64.decode( cipherText );
        String s = new String(cipher.doFinal(decoded), UTF_8);
        return unpadding(s);
    }

    /**
     *  追加补位字符
     *  将输入字符串补位到16位
     *  返回补位后字符串
     *
     * @param data 补位字符串
     * @return 补位后字符串
     */
    static String padding(String data){
        StringBuilder sb = new StringBuilder(data);
        int lengthFactor = 16;
        while(sb.length()% lengthFactor != 0){
            sb.append(PADDING_CHAR);
        }
        return sb.toString();
    }

    /**
     * 剥离补位字符
     * 将补位字符串从输入字符串中剥离
     * 还原字符串返回
     *
     * @param data 剥离补位字符串
     * @return 还原后字符串
     */
    static String unpadding(String data){
        StringBuilder sb = new StringBuilder(data);
        while(sb.length()>0 && sb.charAt(sb.length()-1) == PADDING_CHAR){
            sb.deleteCharAt(sb.length()-1);
        }
        return sb.toString();
    }
    /**
     * 测试用
     *
     * @param args String[]
     */
    public static void main(String[] args) {
        PasswordHelper passwordHelper = new PasswordHelper();
        String str = "admin";

        String encode = "";
        String decode = "";
        try {
            encode = passwordHelper.encrypt( str );
            decode = passwordHelper.decrypt( encode );
        } catch (Exception e) {
            e.printStackTrace();
        }
        System.out.printf( "加密后：" + encode );
        System.out.printf( "解密后：" + decode );

    }
}
